Apple II
Technical Notes
_____________________________________________________________________________
                                                  Developer Technical Support


Apple IIGS
#39:    Mega II Video Counters

Revised by:    Matt Deatherage & Jim Mensch                     November 1988
Written by:    J. Rickard                                            May 1988

This Technical Note describes the Mega II video output registers, which your 
applications can use to get information about where the beam is on the Apple 
IIGS display.
_____________________________________________________________________________

The Mega II controls video timing for the Apple IIGS with a 16-bit counter 
split into a 7-bit horizontal and a 9-bit vertical part (see Figure 1 below).  
The counter outputs are made available to programs running on the machine 
through two addresses in the I/O space, $C02E for the vertical count and $C02F 
for the horizontal count.  These outputs can be used by a program for finer 
control over display update timing.

      _______________________________________________________________
     |          Vertical Counter         |     Horizontal Counter    |
     |___________________________________|___________________________|
     | V5| V4| V3| V2| V1| V0| VC| VB| VA|HPE| H5| H4| H3| H2| H1| H0|
     |_______________________________|___|___________________________|
     |            $E0C02E            |             $E0C02F           |
     |_______________________________________________________________|

                       Figure 1 - Mega II Video Counter

You can see that one bit of the nine-bit vertical counter is in location 
$E0C02F with the seven bits of the horizontal counter.  Keep this in mind when 
reading the counters.

The 7-bit horizontal counter starts at $00 and counts from $40 to $7F (the 
sequence is $00, $40, $41,...,$7E, $7F, $00, $40,...).  The active video time 
consists of 40 one µsec clock cycles starting with $58 and ending with $7F.  
Since this count changes at 980 nanosecond intervals, it will probably be of 
little use to most programs.

The 9-bit vertical counter ranges from $FA through $1FF (250 through 511) in 
NTSC mode (vertical line count of 262), and ranges from $C8 through $1FF (200 
through 511) in PAL video timing mode (with a vertical line count of 312).  
The vertical count will change at 63.7 µsec intervals, giving a program time 
to respond to a specific count before it changes.  The vertical counter byte, 
at $E0C02E, will only change half as often (at 127 µsec intervals) since the 
lowest bit of the 9-bit counter is actually stored in the next byte (at 
$E0C02F). 

The 9-bit counter consists of bits VA, VB, VC, V0, V1, V2, V3, V4 and V5.  
Bits V0 through V5 can be read as a six-bit value.  If this value is between 0 
and 23, it is the line on the text screen currently being updated.  Other 
values indicate the vertical blanking cycle is occurring.  Bits VA through VC 
can be read as a three-bit value (0-7) indicating which scan line of a text 
character (characters are composed of eight lines) is currently being drawn.

The vertical counter can also be used to determine which scan line (0-191 for 
most video modes, including high-resolution and double high-resolution, and 0-
199 for super high-resolution) is being updated at any given moment.

Example

Suppose you want to repaint a portion of the super high-resolution screen that 
will require more time than the vertical blanking period allows.  You will 
have a tear in your animation when the screen's refresh cycle catches up with 
your drawing.

One solution to this problem would be locating the approximate place the tear 
occurs and starting your drawing when the system is scanning that line of 
graphics.  Let's say you are painting an area that is about (for example) 100 
pixels wide and 200 pixels tall in 320 mode, and that the tear will occur 
somewhere around scan line 80.  To avoid the tear, you would wait until the 
system is scanning line 80, then you would start redrawing at the top of the 
screen.  This way, you should be finished drawing when the system is back to 
scanning line 80 again and you will have flicker-free screen updating.

The tricky part is trying to determine just when the system is scanning the 
any given scan line.  One way to determine this is to examine the Mega II 
video counter registers at $E0C02E (vertical) and $E0C02F (horizontal), 
described above.  By using some simple arithmetic you can come up with the 
exact scan line being updated.  Here is a machine language sample of the 
algorithm that waits for scan line 80 (assuming full-native mode):

WhichLine    ANOP
             lda    >$E0C02E     ; get the vertical and horizontal counters
             and    #$80FF       ; strip out the horizontal counter
             dec    A            ; subtract one from the low byte
             XBA                 ; swap low and high bytes
             asl    A            ; shift the significant 8 bits into the 
high byte
             xba                 ; the scan line number is now in A!
             cmp    #80          ; test to see if it's the 80th line
             bne    WhichLine    ; if not, keep waiting
             ...                 ; if so, start redrawing!

The output of this example is the actual scan line number.  If the number is 
200 or greater (192 or greater for modes other than super high-resolution), 
the system is in the VBL cycle.

Note that setting a scan line interrupt is another way to determine when a 
particular super high-resolution scan line is being drawn.  However, you must 
be careful in turning scan line interrupts on and off so that you do not 
interfere with the cursor in QuickDraw II (which uses scan line interrupts).

